#include <iostream>
#include <memory>
#include <string>

class Computer
{
protected:
    std::string _board;
    std::string _display;
    std::string _os;
public:
    Computer(){}
    void setBoard(const std::string& board) {_board=board; }
    void setDisplay(const std::string& display) {_display=display; }
    virtual void setOs() = 0;
    void showParamaters()
    {
        std::string computer="Computer:{\n";
        computer += "\tboard="+_board+",\n";
        computer += "\tdisplay="+_display+",\n";
        computer += "\tos="+_os+",\n";
        computer += "}\n";
        std::cout<< computer << std::endl;
    }
};

class MacBook : public Computer
{
    virtual void setOs() override{
        _os = "Mac Os x12";
    }
};

class Builder
{
public:
    virtual void buildBoard(const std::string& board) = 0;
    virtual void buildDisplay(const std::string& display) = 0;
    virtual void buildOs() = 0;
    virtual std::shared_ptr<Computer> build() = 0;
  
};

class MosBookBuilder : public Builder
{
private:
    std::shared_ptr<Computer> _computer;
public:
    MosBookBuilder():_computer(new MacBook()){}
    virtual void buildBoard(const std::string& board) override
    {
        _computer->setBoard(board);
    }
    virtual void buildDisplay(const std::string& display) override
    {
        _computer->setDisplay(display);
    }
    virtual void buildOs() override
    {
        _computer->setOs();
    }
    std::shared_ptr<Computer> build()
    {
        return _computer;
    }
};

class Director
{
private:
    std::shared_ptr<Builder> _builder;
public:
    Director(Builder* builder):_builder(builder) {}
    void construct(const std::string& board,const std::string& display)
    {
        _builder->buildBoard(board);
        _builder->buildDisplay(display);
        _builder->buildOs();
    }
};



int main()
{

    Builder* builder=new MosBookBuilder();
    std::unique_ptr<Director> director(new Director(builder));
    director->construct("华硕主板","三星显示器");
    std::shared_ptr<Computer> computer=builder->build();
    computer->showParamaters();
    return 0;
}